package com.by.common.crud;

import cn.hutool.core.map.MapUtil;
import com.by.common.bean.PageBean;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;
import java.util.*;

/**
 * 默认实现
 * public class BaseServiceImpl<T, M extends BaseMapper>：
 * 定义了一个公共（public）的泛型类 BaseServiceImpl。
 * 泛型参数有两个：T 和 M。
 * T 表示业务实体类型，例如用户、订单等具体的数据模型对象。
 * M 是一个泛型参数，并且要求 M 必须是 BaseMapper 或者它的子类/实现类。
 * 这样做的目的是为了让这个服务类能够与具体的映射器接口配合使用。
 * implements BaseService<T>：
 * 这个类实现了 BaseService<T> 接口，这意味着 BaseServiceImpl 需要提供所有在 BaseService<T> 中声明的方法的具体实现。
 * 总结起来，BaseServiceImpl 类是一个通用的服务层实现类，它可以处理任何类型的实体对象和对应的数据库映射操作。
 * 通过这种方式，开发者可以利用继承自 BaseService<T> 接口中的方法来执行基本的 CRUD 操作和其他特定于业务逻辑的功能。
 * 同时，通过绑定到 BaseMapper 接口或其子接口，确保了数据访问逻辑的一致性和可扩展性。
 * 这种设计模式常见于微服务架构中，尤其是在分层架构的应用程序里，用于分离业务逻辑和服务实现细节。
 *
 * @param <T>
 */
public class BaseServiceImpl<T, M extends BaseMapper> implements BaseService<T> {


    @Autowired(required = false)
    protected M baseMapper;

    @Override
    public PageBean query(Map map) {
        // 从map中获取当前页数，若不存在或为null，则默认值为1
        int page = MapUtil.getInt(map, "page");

        // 从map中获取每页显示的记录数量，若不存在或为null，则默认值可能由配置决定或其他逻辑处理
        int pageSize = MapUtil.getInt(map, "pageSize");

        // 使用MyBatis分页插件PageHelper进行物理分页设置
        // 设置完此方法后，紧跟其后的第一个查询语句会受到分页影响
        PageHelper.startPage(page, pageSize);

        // 执行具体的数据查询操作
        List<Map> list = baseMapper.query(map);

        // 获取分页后的信息，并将查询结果封装成PageInfo对象
        PageInfo info = new PageInfo(list);

        // 创建并返回自定义的PageBean对象，包含总记录数、当前页码等信息
        return new PageBean(page, pageSize, info.getTotal(), list);
    }


    @Override
    public int save(T entity) {
        return baseMapper.save(entity);
    }

    @Override
    public int update(T entity) {
        return baseMapper.update(entity);
    }

    @Override
    public int delete(Serializable id) {
        return baseMapper.delete(id);
    }

    @Override
    public T get(Serializable id) {
        return (T) baseMapper.get(id);
    }
}
